The TimeCode Media Handler provides a way to store time code in a QuickTime movie. This media supports SMPTE time code. Typically, an application will add a timecode track when a movie is captured. Since the time code is maintained during Movie editing, it can be queried later to produce an edit list.
TimeCode Track
The information stored in the TimeCode track consists of source identification information (eg. name of the source tape), format information (eg. 29.97 fps, dropframe, etc), and frame numbers (ie. translates into time code given the format information). In a perfect world, you only need to record the time code information for the first frame of a captured movie. Let’s say that the first frame is at time 00:02:13:15 (HH:MM:SS:FF). You record this as a sample in the time code track and this sample lasts for the duration of the movie. Then you can determine the time code for every frame in the movie. In the real world, you may encounter discontinous time code. In this case, you would add another time code sample whenever the discontinuity occurs.
Since the duration of a sample is specified when it is added to a track, you must know the duration the time code is for. You have to add the time code sample after you know how long it is good for.
Source Identification
The source identification information is stored in the TimeCodeDescription. This information is stored as UserData identifying the source material. Use the Movie Toolbox UserData routines to extract and add this information. Use the ‘name’ type to specify the name of the source material as UserDataText. Other information about the source may be stored here in the future. See the “Working With Movie User Data” section inside Chapter 2 of Inside Macintosh QuickTime.
struct TimeCodeDescription {
// standard sample description header
long descSize;
long dataFormat;
long resvd1;
short resvd2;
short dataRefIndex;
// timecode specific stuff
long flags;
TimeCodeDef timeCodeDef;
UserDataAtom srcRef;
};
The TimeCodeDef structure defines the format of the the time code that was added to the TimeCode track.
struct TimeCodeDef {
long flags;
TimeScale fTimeScale;
TimeValue frameDuration;
unsigned char numFrames;
};
enum {
tcDropFrame = 1<<0,
tc24HourMax = 1<<1,
tcNegTimesOK = 1<<2,
tcCounter = 1<<3
};
The tcDropFrame bit in the flags field defines whether the time code was drop frame. The tc24HourMax bit specifies whether the time code wraps at 24 hours (eg. SMPTE). The tcNegTimesOK specifies that negative values are allowed (eg. -00:01:20:15). The tcCounter specifies that the time is a counter position of a tape.
The fTimeScale field of TimeCodeDef is the time scale for interpreting frameDuration. FrameDuration is how long each frame lasts in real time. NumFrames is the number of frames per second for the timecode format. If the time is a counter, this is the number of frames per tick for each counter tick.
For SMPTE NTSC 29.97 frames-per-second drop-frame, a TimeCodeDef would be:
TimeCodeDef.flags = tcDropFrame | tc24HourMax;
TimeCodeDef.fTimeScale= 2997;
TimeCodeDef.frameDuration= 100;
TimeCodeDef.numFrames= 30;
The sample data is the frame number from time zero. For example, if the time code for the material is at 00:00:12:15 for the above TimeCodeDef, the frame number is 12*30+15 = 375. In other words, the beginning of the movie is frame number 375 which is the same as 00:00:12:15 when converted using the previous TimeCodeDef. The TimeCode Media Handler provides routines for doing all the conversions necessary. The sample data is just a long.
Since the original TimeCodeDef is stored, you can readily use the same time code format as the original material. You can also interpret it in another form if you desire.
When frame numbers are converted to and from time code using the TimeCodeDef, the time code is expressed using the TimeCodeRecord.
struct TimeCodeTime {
unsigned char hours;
Boolean isNegative:1;
unsigned char minutes:7;
unsigned char seconds;
unsigned char frames;
};
struct TimeCodeCounter {
long counter;
};
union TimeCodeRecord{
TimeCodeTime t;
TimeCodeCounter c;
};
Note: The interfaces do not define isNegative and minutes as bit fields for portability reasons. Instead, mask the minutes field with tctNegFlag to determine whether the time code is negative.
TimeCodeRecord
As you can see, the TimeCodeRecord handles both time code and counter values. When you directly access a TimeCodeRecord as a TimeCodeTime, it is important to check the negative bit. The TimeCode Media Handler provides routines for converting frameNumbers to and from TimeCodeRecords.
When a TimeCode track is added to a movie, it is vital to indicate which tracks this time code is for. You do this using the new track reference routines (see documention for this elsewhere). Study the code samples closely for adding to and extracting time codes from a movie. The AddTimeCode sample lets you add timecode to a movie. The ExportCMX3600 sample is a QuickTime Movie Export Component which creates a CMX3600 EDL for a Movie with TimeCode.
You can have the time code displayed in the Movie. When displayed, the time code appears in the Track’s rectangle. You must enable the track as well as call TCSetTimeCodeFlags. To turn off the display, disable the track and call TCSetTimeCodeFlags.
This call returns all the information about the TimeCode for the current time in the movie. It returns the frameNumber, the TimeCodeDef, the TimeCodeRecord interpreting the frameNumber using the TimeCodeDef, and the SourceReference. If there are any pieces of information you do not need, just pass nil. If you get a srcRef, don’t forget to call DisposeUserData after you are finished with it.
This call returns all the information about the TimeCode at a given time in the media. It returns the frameNumber, the TimeCodeDef, the TimeCodeRecord interpreting the frameNumber using the TimeCodeDef, and the SourceReference. If there are any pieces of information you do not need, just pass nil. If you get a srcRef, don’t forget to call DisposeUserData after you are finished with it.
This call sets the display options for the TimeCode media. If the time code is displayed in the movie, these options control its characteristics. The TCTextOptions defines the text characteristics used when timecode is displayed.